package com.pobing.cipherlab;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.cipherlab.barcode.*;
import com.cipherlab.barcode.decoder.*;
import com.cipherlab.barcode.decoderparams.*;

import org.apache.cordova.*;
import org.json.JSONArray;
import org.json.JSONException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;

public class CipherLabScannerPlugin extends CordovaPlugin {

    private IntentFilter filter;
    private ReaderManager mReaderManager;
    private CallbackContext receiveScanCallback = null;
    private boolean enableBinaryData = false;

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
        // 默认自动初始化
        this.initialise(receiveScanCallback);
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException
    {

        //System.out.println("============== execute ===========");
        Log.v("CipherlabPlugin", "============== execute ===========: " + action);

        if (action.equals("echo")) {
            String message = args.getString(0);
            this.echo(message, callbackContext);
            return true;
        }

        if (action.equals("initialise")) {
            this.initialise(callbackContext);
            return true;
        }

        if (action.equals("setReceiveScanCallback")) {
            Log.v("CipherlabPlugin", " ==== setReceiveScanCallback ===");
            receiveScanCallback = callbackContext;

            if (callbackContext == null)
            {
                Log.v("CipherlabPlugin", "callbackContext is null.");
            } else {
                Log.v("CipherlabPlugin", "callbackContext is not null");
            }

            return true;
        }

        if (action.equals("requestScan"))
        {

            Log.v("CipherlabPlugin", "requestScan");
            // this.initialise(callbackContext);

            receiveScanCallback = callbackContext;

            return true;
        }

        if (action.equals("destroy"))
        {

            if (mReaderManager != null)
            {
                // Call this from window.onbeforeunload
                Log.v("CipherlabPlugin", "destroy(): cleaning up.");

                // cordova.getActivity().unregisterReceiver(myDataReceiver);
                mReaderManager.Release();

                myDataReceiver = null;
                mReaderManager = null;
            }

            return true;
        }

        if (action.equals("setEnableBinaryData"))
        {
            boolean enable = args.getBoolean(0);
            Log.v("CipherlabPlugin", " ==== setEnableBinaryData: " + enable + " ===");
            this.setEnableBinaryData(callbackContext, enable);
            return true;
        }

        if (action.equals("getEnableBinaryData"))
        {
            this.getEnableBinaryData(callbackContext);
            return true;
        }

        Log.v("CipherlabPlugin", "============== done   ===========: " + action);

        return false;
    }

    public void receieveScan(String data, String type, byte [] binary)
    {
        Log.v("CipherlabPlugin", "============== receieveScan START   ===========: ");
        Log.v("CipherlabPlugin", "============== data: " + data);
        Log.v("CipherlabPlugin", "============== type: " + type);

        ArrayList<PluginResult> arguments = new ArrayList<PluginResult>();
        arguments.add(new PluginResult(PluginResult.Status.OK, data));
        arguments.add(new PluginResult(PluginResult.Status.OK, type));

        // 默认不走
        if (this.getEnableBinaryData()) {
            // MDR 24/04/2018 - byte array doesn't get passed through properly, convert to integer array
            JSONArray integers = new JSONArray();

            for (int x = 0; x < binary.length; x++) {
                integers.put((int)binary[x] & 0xFF);
            }

            arguments.add(new PluginResult(PluginResult.Status.OK, integers));
        }

        PluginResult progressResult = new PluginResult(PluginResult.Status.OK, arguments);

        Log.v("CipherlabPlugin", "============== progressResult: " + progressResult.toString());

        progressResult.setKeepCallback(true);

        Log.v("CipherlabPlugin", "receiveScanCallback == null?");

        if (receiveScanCallback == null)
        {
            Log.v("CipherlabPlugin", "receiveScanCallback is null.");
        } else {
            Log.v("CipherlabPlugin", "receiveScanCallback is not null.");
            receiveScanCallback.sendPluginResult(progressResult);
        }
    }

    private void echo(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }

    public void initialise(CallbackContext callbackContext)
    {
        Log.v("CipherlabPlugin", "CipherlabPlugin.initialise()");
        try
        {
            Log.v("CipherlabPlugin", "com.cipherlab.barcode.GeneralString.Intent_SOFTTRIGGER_DATA: " + com.cipherlab.barcode.GeneralString.Intent_SOFTTRIGGER_DATA);
            if (cordova.getActivity() == null)
            {
                Log.v("CipherlabPlugin", "cordova.getActivity() is null");
            } else {
                Log.v("CipherlabPlugin", "cordova.getActivity() is something");
            }

            filter = new IntentFilter();
            filter.addAction(com.cipherlab.barcode.GeneralString.Intent_SOFTTRIGGER_DATA);
            filter.addAction(com.cipherlab.barcode.GeneralString.Intent_PASS_TO_APP);
            filter.addAction(com.cipherlab.barcode.GeneralString.Intent_READERSERVICE_CONNECTED);

            mReaderManager = ReaderManager.InitInstance(cordova.getContext());
            cordova.getContext().registerReceiver(myDataReceiver, filter);

            Log.v("CipherlabPlugin", "Got reader");
        } catch (Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();

            Log.v("CipherlabPlugin", "Error starting reader manager: " + stackTrace);
        }

        Log.v("CipherlabPlugin", "CipherlabPlugin.initialise() Done");

       // callbackContext.success();
    }

    public void setEnableBinaryData(CallbackContext callbackContext, boolean enable) {
        this.enableBinaryData = enable;
        callbackContext.success();
    }

    private void getEnableBinaryData(CallbackContext callbackContext) {
        Log.v("CipherlabPlugin", "getEnableBinaryData: " + Boolean.toString(this.getEnableBinaryData()));
        callbackContext.success(Boolean.toString(this.getEnableBinaryData()));
    }

    public boolean getEnableBinaryData() {
        return this.enableBinaryData;
    }

    /// create a BroadcastReceiver for receiving intents from barcode reader service
    private BroadcastReceiver myDataReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(GeneralString.Intent_SOFTTRIGGER_DATA) || intent.getAction().equals(GeneralString.Intent_PASS_TO_APP)) {

                byte [] binary = null;

                if (getEnableBinaryData())
                    binary = intent.getByteArrayExtra(GeneralString.BcReaderDataArray);

                String data = intent.getStringExtra(GeneralString.BcReaderData);
                Log.v("CipherlabPlugin", "原始data: " + data);

                int type = intent.getIntExtra(GeneralString.BcReaderCodeType, 0);

                BcDecodeType barcodeType = BcDecodeType.valueOf(type);

                Log.v("CipherlabPlugin", "got data: " + data);
                receieveScan(data, barcodeType.name().toUpperCase(), binary);
            } else if(intent.getAction().equals(GeneralString.Intent_READERSERVICE_CONNECTED)){

                BcReaderType myReaderType =  mReaderManager.GetReaderType();

                ReaderOutputConfiguration settings = new ReaderOutputConfiguration();
                mReaderManager.Get_ReaderOutputConfiguration(settings);
                settings.enableKeyboardEmulation = KeyboardEmulationType.None;
                mReaderManager.Set_ReaderOutputConfiguration(settings);

                Log.v("CipherlabPlugin", "got data, 3");

			/*NotificationParams settings = new NotificationParams();
			mReaderManager.Get_NotificationParams(settings);

			ReaderOutputConfiguration settings2 = new ReaderOutputConfiguration();
			mReaderManager.Get_ReaderOutputConfiguration(settings2);
			*/
            }

        }
    };
}
